home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / glibmm-2.4 / glibmm / value_custom.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-04-20  |  7.7 KB  |  290 lines

  1. // -*- c++ -*-
  2. /* $Id: value_custom.h,v 1.8 2005/01/21 19:26:04 murrayc Exp $ */
  3.  
  4. /* Copyright 2002 The gtkmm Development Team
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Library General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Library General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Library General Public
  17.  * License along with this library; if not, write to the Free
  18.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  22. #ifndef _GLIBMM_VALUE_H_INCLUDE_VALUE_CUSTOM_H
  23. #error "glibmm/value_custom.h cannot be included directly"
  24. #endif
  25. #endif
  26.  
  27. #include <new>
  28. #include <typeinfo>
  29. #include <glibmmconfig.h>
  30.  
  31. GLIBMM_USING_STD(nothrow)
  32.  
  33.  
  34. namespace Glib
  35. {
  36.  
  37. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  38.  
  39. extern "C"
  40. {
  41.   typedef void (* ValueInitFunc) (GValue*);
  42.   typedef void (* ValueFreeFunc) (GValue*);
  43.   typedef void (* ValueCopyFunc) (const GValue*, GValue*);
  44. }
  45.  
  46. /* When using Glib::Value<T> with custom types, each T will be registered
  47.  * as subtype of G_TYPE_BOXED, via this function.  The type_name argument
  48.  * should be the C++ RTTI name.
  49.  */
  50. GType custom_boxed_type_register(const char*   type_name,
  51.                                  ValueInitFunc init_func,
  52.                                  ValueFreeFunc free_func,
  53.                                  ValueCopyFunc copy_func);
  54.  
  55. /* When using Glib::Value<T*> or Glib::Value<const T*> with custom types,
  56.  * each T* or const T* will be registered as a subtype of G_TYPE_POINTER,
  57.  * via this function.  The type_name argument should be the C++ RTTI name.
  58.  */
  59. GType custom_pointer_type_register(const char* type_name);
  60.  
  61. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  62.  
  63.  
  64. /**
  65.  * @ingroup glibmmValue
  66.  */
  67. template <class T, class PtrT>
  68. class Value_Pointer : public ValueBase_Object
  69. {
  70. public:
  71.   typedef PtrT  CppType;
  72.   typedef void* CType;
  73.  
  74.   static inline GType value_type() G_GNUC_CONST;
  75.  
  76.   inline void set(CppType data);
  77.   inline CppType get() const;
  78.  
  79. private:
  80.   inline
  81.   static GType value_type_(Glib::Object*);
  82.   static GType value_type_(void*);
  83.  
  84.   inline void set_(CppType data, Glib::Object*);
  85.   inline void set_(CppType data, void*);
  86.  
  87.   inline CppType get_(Glib::Object*) const;
  88.   inline CppType get_(void*) const;
  89. };
  90.  
  91.   
  92. /** Generic value implementation for custom types.
  93.  * @ingroup glibmmValue
  94.  * Any type to be used with this template must implement:
  95.  * - default constructor
  96.  * - copy constructor
  97.  * - assignment operator
  98.  * - destructor
  99.  *
  100.  * Compiler-generated implementations are OK, provided they do the
  101.  * right thing for the type.  In other words, any type that works with
  102.  * <tt>std::vector</tt> will work with Glib::Value<>.
  103.  *
  104.  * @note None of the operations listed above are allowed to throw.  If you
  105.  * cannot ensure that no exceptions will be thrown, consider using either
  106.  * a normal pointer or a smart pointer to hold your objects indirectly.
  107.  */
  108. template <class T>
  109. class Value : public ValueBase_Boxed
  110. {
  111. public:
  112.   typedef T  CppType;
  113.   typedef T* CType;
  114.  
  115.   static GType value_type() G_GNUC_CONST;
  116.  
  117.   inline void set(const CppType& data);
  118.   inline CppType get() const;
  119.  
  120. private:
  121.   static GType custom_type_;
  122.  
  123.   static void value_init_func(GValue* value);
  124.   static void value_free_func(GValue* value);
  125.   static void value_copy_func(const GValue* src_value, GValue* dest_value);
  126. };
  127.  
  128.  
  129. /** Specialization for pointers to instances of any type.
  130.  * @ingroup glibmmValue
  131.  * No attempt is made to manage the memory associated with the
  132.  * pointer, you must take care of that yourself.
  133.  */
  134. template <class T>
  135. class Value<T*> : public Value_Pointer<T,T*>
  136. {};
  137.  
  138. /** Specialization for pointers to const instances of any type.
  139.  * @ingroup glibmmValue
  140.  * No attempt is made to manage the memory associated with the
  141.  * pointer, you must take care of that yourself.
  142.  */
  143. template <class T>
  144. class Value<const T*> : public Value_Pointer<T,const T*>
  145. {};
  146.  
  147.  
  148. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  149.  
  150. /**** Glib::Value_Pointer<T, PtrT> *****************************************/
  151.  
  152. /** Implementation for Glib::Object pointers **/
  153.  
  154. // static
  155. template <class T, class PtrT> inline
  156. GType Value_Pointer<T,PtrT>::value_type_(Glib::Object*)
  157. {
  158.   return T::get_base_type();
  159. }
  160.  
  161. template <class T, class PtrT> inline
  162. void Value_Pointer<T,PtrT>::set_(PtrT data, Glib::Object*)
  163. {
  164.   set_object(const_cast<T*>(data));
  165. }
  166.  
  167. //More spec-compliant compilers (such as Tru64) need this to be near Glib::Object instead.
  168. #ifdef GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
  169. template <class T, class PtrT> inline
  170. PtrT Value_Pointer<T,PtrT>::get_(Glib::Object*) const
  171. {
  172.   return dynamic_cast<T*>(get_object());
  173. }
  174. #endif //GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
  175.  
  176. /** Implementation for custom pointers **/
  177.  
  178. // static
  179. template <class T, class PtrT>
  180. GType Value_Pointer<T,PtrT>::value_type_(void*)
  181. {
  182.   static GType custom_type = 0;
  183.  
  184.   if(!custom_type)
  185.     custom_type = Glib::custom_pointer_type_register(typeid(PtrT).name());
  186.  
  187.   return custom_type;
  188. }
  189.  
  190. template <class T, class PtrT> inline
  191. void Value_Pointer<T,PtrT>::set_(PtrT data, void*)
  192. {
  193.   gobject_.data[0].v_pointer = const_cast<T*>(data);
  194. }
  195.  
  196. template <class T, class PtrT> inline
  197. PtrT Value_Pointer<T,PtrT>::get_(void*) const
  198. {
  199.   return static_cast<T*>(gobject_.data[0].v_pointer);
  200. }
  201.  
  202. /** Public forwarding interface **/
  203.  
  204. // static
  205. template <class T, class PtrT> inline
  206. GType Value_Pointer<T,PtrT>::value_type()
  207. {
  208.   // Dispatch to the specific value_type_() overload.
  209.   return Value_Pointer<T,PtrT>::value_type_(static_cast<T*>(0));
  210. }
  211.  
  212. template <class T, class PtrT> inline
  213. void Value_Pointer<T,PtrT>::set(PtrT data)
  214. {
  215.   // Dispatch to the specific set_() overload.
  216.   this->set_(data, static_cast<T*>(0));
  217. }
  218.  
  219. template <class T, class PtrT> inline
  220. PtrT Value_Pointer<T,PtrT>::get() const
  221. {
  222.   // Dispatch to the specific get_() overload.
  223.   return this->get_(static_cast<T*>(0));
  224. }
  225.  
  226.  
  227. /**** Glib::Value<T> *******************************************************/
  228.  
  229. // Static data, specific to each template instantiation.
  230. template <class T>
  231. GType Value<T>::custom_type_ = 0;
  232.  
  233. template <class T> inline
  234. void Value<T>::set(const typename Value<T>::CppType& data)
  235. {
  236.   // Assume the value is already default-initialized.  See value_init_func().
  237.   *static_cast<T*>(gobject_.data[0].v_pointer) = data;
  238. }
  239.  
  240. template <class T> inline
  241. typename Value<T>::CppType Value<T>::get() const
  242. {
  243.   // Assume the pointer is not NULL.  See value_init_func().
  244.   return *static_cast<T*>(gobject_.data[0].v_pointer);
  245. }
  246.  
  247. // static
  248. template <class T>
  249. GType Value<T>::value_type()
  250. {
  251.   if(!custom_type_)
  252.   {
  253.     custom_type_ = Glib::custom_boxed_type_register(
  254.         typeid(CppType).name(),
  255.         &Value<T>::value_init_func,
  256.         &Value<T>::value_free_func,
  257.         &Value<T>::value_copy_func);
  258.   }
  259.   return custom_type_;
  260. }
  261.  
  262. // static
  263. template <class T>
  264. void Value<T>::value_init_func(GValue* value)
  265. {
  266.   // Never store a NULL pointer (unless we're out of memory).
  267.   value->data[0].v_pointer = new(std::nothrow) T();
  268. }
  269.  
  270. // static
  271. template <class T>
  272. void Value<T>::value_free_func(GValue* value)
  273. {
  274.   delete static_cast<T*>(value->data[0].v_pointer);
  275. }
  276.  
  277. // static
  278. template <class T>
  279. void Value<T>::value_copy_func(const GValue* src_value, GValue* dest_value)
  280. {
  281.   // Assume the source is not NULL.  See value_init_func().
  282.   const T& source = *static_cast<T*>(src_value->data[0].v_pointer);
  283.   dest_value->data[0].v_pointer = new(std::nothrow) T(source);
  284. }
  285.  
  286. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  287.  
  288. } // namespace Glib
  289.  
  290.